package com.rtsapp.server.domain.mysql.hibernate.impl;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import com.rtsapp.server.logger.Logger;
import com.rtsapp.server.logger.LoggerFactory;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.TransactionException;

import com.rtsapp.server.domain.mysql.hibernate.IEntityTransaction;

public class DirectTransaction implements IEntityTransaction {

	private static final Logger logger = LoggerFactory.getLogger( DirectTransaction.class);

	private Session session = null;
	private Transaction tx = null;

	public DirectTransaction() {
		if (logger.isDebugEnabled()) {
			long openTimes = HibernateUtils.getSessionOpenTimes();
			long closeTimes = HibernateUtils.getSessionCloseTimes();
			logger.debug(" HibernateSession openTimes=" + openTimes
					+ ", closeTimes=" + closeTimes);
		}
	}

	@Override
	public void begin() {
		logger.info("begin()");
		session = HibernateUtils.openSession();
		if (session == null) {
			logger.error("Hibernate Session为空");
			return;
		}
		tx = session.beginTransaction();
	}

	@Override
	public void commit() {
		logger.info("commit()");
		tx.commit();
	}

	@Override
	public void rollback() {
		logger.info("rollback()");
		if (tx != null) {
			try {
				tx.rollback();
			} catch (TransactionException te) {
				logger.error("HibernateTransaction rollback failed", te);
			}
		} else {
			logger.warn("tx==null");
		}
	}

	@Override
	public void close() {
		logger.info("close()");
		HibernateUtils.closeSession(session);
		session = null;
	}

	@Override
	public void insert(Object entity) {
		logger.info("insert(entity)");
		session.save(entity);
	}

	@Override
	public void insert(List<?> entityList) {
		logger.info("insert(entityList)");
		for (Object entity : entityList) {
			session.save(entity);
		}
	}

	@Override
	public void insert(Object... objects) {
		logger.info("insert(objects)");
		if (objects != null) {
			for (Object entity : objects) {
				session.save(entity);
			}
		} else {
			logger.warn("objects==null");
		}
	}

	@Override
	public void update(Object entity) {
		logger.info("update(entity)");
		session.update(entity);
	}

	@Override
	public void update(List<?> entityList) {
		logger.info("update(entityList)");
		for (Object entity : entityList) {
			session.update(entity);
		}
	}

	@Override
	public void update(Object... objects) {
		logger.info("update(objects)");
		if (objects != null) {
			for (Object entity : objects) {
				session.update(entity);
			}
		} else {
			logger.warn("objects==null");
		}
	}

	@Override
	public void delete(Object entity) {
		logger.info("delete(entity)");
		session.delete(entity);
	}

	@Override
	public void delete(List<?> entityList) {
		logger.info("delete(entityList)");
		for (Object entity : entityList) {
			session.delete(entity);
		}
	}

	@Override
	public void delete(Object... objects) {
		logger.info("delete(objects)");
		if (objects != null) {
			for (Object entity : objects) {
				session.delete(entity);
			}
		} else {
			logger.warn("objects==null");
		}
	}

	/**
	 * 按id查询对象
	 * 
	 * @param entityClass
	 * @param id
	 * @return
	 */
	@Override
	public Object get(Class<?> entityClass, Serializable id) {
		logger.info("get(entityClass, id)");
		Object entity = session.get(entityClass, id);
		return entity;
	}

	@Override
	public List<?> get(Class<?> entityClass, List<Serializable> idList) {
		logger.info("get(entityClass, idList)");
		List<Object> entityList = new ArrayList<Object>();
		for (Serializable id : idList) {
			Object entity = session.get(entityClass, id);
			entityList.add(entity);
		}
		return entityList;
	}

	@Override
	public List<Object> get(Class<?> entityClass, Serializable... ids) {
		logger.info("get(entityClass, ids)");
		List<Object> entityList = new ArrayList<Object>();
		if (ids != null) {
			for (Serializable id : ids) {
				Object entity = session.get(entityClass, id);
				entityList.add(entity);
			}
		} else {
			logger.warn("ids==null");
		}
		return entityList;
	}

	/**
	 * 执行查询操作
	 * 
	 * @param hql
	 * @param objects
	 * @return
	 */
	@Override
	public List<?> queryListLimit(int firstResult, int maxResults, String hql,
			Object... params) {
		logger.info("queryListLimit(firstResult, maxResults, hql, params)");
		List<?> result = null;
		Query query = session.createQuery(hql);
		if (params != null) {
			begin();
			for (int i = 0; i < params.length; i++) {
				query.setParameter(i, params[i]);
			}
		} else {
			logger.warn("params==null");
		}
		query.setFirstResult(firstResult);
		query.setMaxResults(maxResults);
		result = query.list();
		return result;
	}

	/**
	 * 执行查询操作
	 * 
	 * @param hql
	 * @param objects
	 * @return
	 */
	@Override
	public List<?> queryList(String hql, Object... params) {
		logger.info("queryList(hql, params)");
		Query query = session.createQuery(hql);
		if (params != null) {
			for (int i = 0; i < params.length; i++) {
				query.setParameter(i, params[i]);
			}
		} else {
			logger.warn("params==null");
		}
		List<?> result = query.list();
		return result;

	}

	@Override
	public Object queryUnique(String hql, Object... params) {
		logger.info("queryUnique(hql, params)");
		Query query = session.createQuery(hql);
		if (params != null) {
			for (int i = 0; i < params.length; i++) {
				query.setParameter(i, params[i]);
			}
		} else {
			logger.warn("params==null");
		}
		Object result = query.uniqueResult();
		return result;
	}

	/**
	 * 执行hql更改操作
	 * 
	 * @param hql
	 * @param objects
	 * @return
	 */
	@Override
	public int executeUpdate(String hql, Object... params) {
		logger.info("executeUpdate(hql, params)");
		Query query = session.createQuery(hql);
		if (params != null) {
			for (int i = 0; i < params.length; i++) {
				query.setParameter(i, params[i]);
			}
		} else {
			logger.warn("params==null");
		}
		int updateLine = query.executeUpdate();
		return updateLine;
	}
}